package com.eastmoney.emis.edda.infrastructure.hsbc;

import com.eastmoney.emis.edda.config.HsbcEddaConfig;
import com.eastmoney.emis.edda.infrastructure.hsbc.annotation.HsbcLog;
import com.eastmoney.emis.edda.infrastructure.hsbc.dto.*;
import com.eastmoney.emis.edda.projection.HsbcEddaContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Repository;
import org.springframework.web.client.ResourceAccessException;
import org.springframework.web.client.RestTemplate;

import javax.annotation.PostConstruct;

/**
 * @description: Description
 * @projectName: EDDA-HSBC
 * @package: com.eastmoney.emis.edda.infrastructure.impl
 * @author: 汪程程
 * @date: 2022/9/26 5:00 PM
 * @version: 1.0
 */
@Repository
public class HsbcEddaApiImpl implements HsbcEddaApi {
    @Autowired
    private HsbcEddaConfig eddaConfig;
    @Autowired
    @Qualifier("hsbcEddaRestTemplate")
    private RestTemplate hsbcEddaRestTemplate;
    @PostConstruct
    public void init() {

    }

    private String requestUrl(String uri) {
        return eddaConfig.getBaseUrl() + uri;
    }

    @HsbcLog(action = "/authorisations")
    @Override
    public AuthResp authorization(AuthReq authReq) {
        String uri = "/v1/direct-debits/authorisations";
        return doRequest(requestUrl(uri), authReq, AuthResp.class);
    }

    @HsbcLog(action = "/authorisations-status")
    @Override
    public AuthEnquiryResp authorizationStatus(AuthEnquiryReq authEnquiryReq) {
        String uri = "/v1/direct-debits/authorisations-status";
        return doRequest(requestUrl(uri), authEnquiryReq, AuthEnquiryResp.class);

    }

    @HsbcLog(action = "/otp-confirmation")
    @Override
    public OTPConfirmResp otpConfirmation(OTPConfirmReq otpConfirmReq) {
        String uri = "/v1/direct-debits/authorisations/otp-confirmation";
        return doRequest(requestUrl(uri), otpConfirmReq, OTPConfirmResp.class);
    }

    @HsbcLog(action = "/otp-regeneration")
    @Override
    public OTPRegenerationResp reGenerateOtpCode(OTPRegenerationReq otpRegenerationReq) {
        String uri = "/v1/direct-debits/authorisations/otp-regeneration";
        return doRequest(requestUrl(uri), otpRegenerationReq, OTPRegenerationResp.class);
    }

    @HsbcLog(action = "/instructions")
    @Override
    public InstructionResp debitInstruction(InstructionReq instructionReq) {
        String uri = "/v1/direct-debits/instructions";
        return doRequest(requestUrl(uri), instructionReq, InstructionResp.class);
    }

    @HsbcLog(action = "/instructions-status")
    @Override
    public InstructionStatusResp debitInstructionStatus(InstructionStatusReq instructionStatusReq) {
        String uri = "/v1/direct-debits/instructions-status";
        return doRequest(requestUrl(uri), instructionStatusReq, InstructionStatusResp.class);
    }

    @HsbcLog(action = "/reports")
    @Override
    public ReportsResp report(ReportsReq reportsReq) {
        String uri = "/v1/direct-debits/reports";
        return doRequest(requestUrl(uri), reportsReq, ReportsResp.class);
    }

    private <T, K extends HsbcEddaBaseResp> K doRequest(String url, T req, Class<K> clazz) {
        try {
            return hsbcEddaRestTemplate.postForObject(url, req, clazz);
        } catch (ResourceAccessException e) {
            try {
                K k = clazz.getDeclaredConstructor().newInstance();
                HsbcEddaContext context = HsbcEddaApi.CONTEXT.get();
                context.setRespPayload(e.getMessage());
                k.Message = e.getMessage();
                k.context(context);
                k.setNetworkError(true);
                return k;
            } catch (Exception ex) {
                throw new RuntimeException(ex);
            }
        }

    }

}
